/*
 * Copyright (C) 2012 Santiago Valdarrama
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package com.yuanmei.stockeyes.artifacts;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
//import java.util.Locale;

import android.app.Notification;
import android.app.NotificationManager;
//import android.annotation.SuppressLint;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.BatteryManager;
import android.os.Build;
import android.util.Log;
import android.view.View;

//import com.yuanmei.stockeyes.MarketCollectorService;
import com.yuanmei.stockeyes.R;
import com.yuanmei.stockeyes.model.Stock;
import com.yuanmei.stockeyes.receivers.MarketCollectionReceiver;
import com.yuanmei.stockeyes.activities.DashboardActivity;

public class Extensions {
    private final static String LOG_TAG = "Extensions";
    private static int sCurrentNotifyId = 0;

    public enum PatternBackgroundColor {
        BLACK, BLUE, GREEN, RED, BROWN
    }

    public static int dpToPixels(Resources resources, int dp) {
        final float scale = resources.getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    public static int spToPixels(Context context, float sp) {
        final float scale = context.getResources().getDisplayMetrics().scaledDensity;
        return (int) (sp * scale + 0.5f);
    }

    public static String format(float value) {
        return new DecimalFormat("#,##0.00").format(value);
    }

    public static String formatShares(float value) {
        return new DecimalFormat("#,##0.###").format(value);
    }

    public static String toValueOrEmptyString(String value) {
        if (value.equals("-")) {
            return "";
        }

        return value;
    }

    public static String fromValueToAbbreviation(float value) {

        float abs_value = Math.abs(value);

        String sign = "";
        if (abs_value < 10000) {
            BigDecimal b0 = new BigDecimal(((int)value)).setScale(2, BigDecimal.ROUND_HALF_UP);
            return b0.toString();
        }

        if (abs_value > 100000000) {
            value /= 100000000;
            sign = "亿";
        } else if (abs_value > 10000) {
            value /= 10000;
            sign = "万";
        }

        BigDecimal b1 = new BigDecimal(value).setScale(2, BigDecimal.ROUND_HALF_UP);
        //return new DecimalFormat("#.00").format(value) + sign;
        return b1.toString() + sign;
    }

    public static String fromTurnOverToShort(float value) {
        String sign = "元";
        if (value > 100000000) {
            value /= 100000000;
            sign = "亿元";
        } else if (value > 10000) {
            value /= 10000;
            sign = "万元";
        }
        BigDecimal b1 = new BigDecimal(value).setScale(2,
                BigDecimal.ROUND_HALF_UP);
        // return new DecimalFormat("#.00").format(value) + sign;
        return b1.toString() + sign;
    }

    public static String fromVolumeToShortHand(float value) {
        String sign = "手";
        if (value > 100000000) {
            value /= 100000000;
            sign = "亿手";
        } else if (value > 10000) {
            value /= 10000;
            sign = "万手";
        }
        BigDecimal b1 = new BigDecimal(value).setScale(2, BigDecimal.ROUND_HALF_UP);
        //return new DecimalFormat("#.00").format(value) + sign;
        return b1.toString() + sign;
    }

    public static Float fromStringToFloat(String value) {
        float multiplier = 1f;

        if (value.endsWith("B")) {
            value = value.substring(0, value.length() - 1);
            multiplier = 1000000000f;
        } else if (value.endsWith("M")) {
            value = value.substring(0, value.length() - 1);
            multiplier = 1000000f;
        }

        Float result;

        try {
            result = Float.parseFloat(value);
        } catch (NumberFormatException e) {
            result = null;
        }

        return result != null
                ? result * multiplier
                : null;
    }

    public static int dividerLineResourceId(Stock stock) {
        if (stock.isDown()) {
            return R.drawable.divider_horizontal_red;
        }

        if (stock.isUp()) {
            return R.drawable.divider_horizontal_green;
        }

        return R.drawable.divider_horizontal_black;
    }

    public static int chartFillColor(Stock stock) {
        return stock.isDown()
                ? Color.rgb(112, 39, 37)
                : Color.rgb(71, 87, 33);
    }

    public static int chartGridColor(Stock stock) {
        return stock.isDown()
                ? Color.rgb(190, 67, 61)
                : Color.rgb(131, 161, 61);
    }

    public static void applyPattern(Resources resources, View content, Stock stock) {
        if (stock.isDown()) {
            applyPattern(resources, content, PatternBackgroundColor.GREEN);
        } else if (stock.isUp()) {
            applyPattern(resources, content, PatternBackgroundColor.RED);
        } else {
            applyPattern(resources, content, PatternBackgroundColor.BLACK);
        }
    }

    @SuppressWarnings("deprecation")
    public static void applyPattern(Resources resources, View view, PatternBackgroundColor patternBackgroundColor) {
        StateListDrawable stateListDrawable = new StateListDrawable();
        stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, Extensions.getPatternDrawable(resources, PatternBackgroundColor.BLUE));
        stateListDrawable.addState(new int[]{}, Extensions.getPatternDrawable(resources, getPatternResourceId(patternBackgroundColor)));
        view.setBackgroundDrawable(stateListDrawable);
    }

    private static Drawable getPatternDrawable(Resources resources, PatternBackgroundColor patternBackgroundColor) {
        return getPatternDrawable(resources, getPatternResourceId(patternBackgroundColor));
    }

    private static Drawable getPatternDrawable(Resources resources, int resourceId) {
        BitmapDrawable drawable = new BitmapDrawable(resources, BitmapFactory.decodeResource(resources, resourceId));
        drawable.setTileModeX(Shader.TileMode.REPEAT);
        drawable.setTileModeY(Shader.TileMode.REPEAT);

        return drawable;
    }

    private static int getPatternResourceId(PatternBackgroundColor patternBackgroundColor) {
        int resourceId;
        switch (patternBackgroundColor) {
            case BLUE:
                resourceId = R.drawable.pattern_background_blue;
                break;
            case GREEN:
                resourceId = R.drawable.pattern_background_green;
                break;
            case RED:
                resourceId = R.drawable.pattern_background_red;
                break;
            case BROWN:
                resourceId = R.drawable.pattern_background_brown;
                break;
            default:
                resourceId = R.drawable.pattern_background_black;
                break;
        }

        return resourceId;
    }

    public static boolean isPriorHoneycomb() {
        return Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB;
    }

    public static boolean isHoneycombOrLater() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB;
    }

    public static boolean isIceCreamSandwichOrLater() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;
    }

    public static boolean isPriorIceCreamSandwich() {
        return Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH;
    }

    public static boolean isOrientationPortrait(Resources resources) {
        return resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
    }

    public static Stock findStock(List<Stock> stocks, String code) {
        for (Stock stock : stocks) {
            if (stock.getCode().toUpperCase().equals(code.toUpperCase())) {
                return stock;
            }
        }

        return null;
    }

    public static boolean isTheBatteryPluggedIn(Context context) {
        Intent batteryIntent = context.getApplicationContext().registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        int plugged = batteryIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
        return plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB;
    }

    public static boolean areWeOnline(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

        return networkInfo != null
                ? networkInfo.isConnected()
                : false;
    }

    public static void sendDogNotification(Context context, String msg) {
        NotificationManager nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        //Notification n = new Notification(R.drawable.ic_window_title_red, msg, System.currentTimeMillis());
        //     n.flags = Notification.FLAG_AUTO_CANCEL;
        Intent nIntent = new Intent(context, DashboardActivity.class);
        int currId = ++sCurrentNotifyId;
        nIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent contentIntent = PendingIntent.getActivity(context, currId, nIntent, 0);
        Notification noti = new Notification.Builder(context)
                .setContentTitle(context.getString(R.string.notification_title))
                .setContentText(msg)
                .setSmallIcon(R.drawable.ic_window_title_red)
                .setAutoCancel(true)
                .setContentIntent(contentIntent)
                .setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_LIGHTS)
                .build();

        nm.notify(R.string.application_name + currId, noti);
    }

    public static boolean areWeUsingWiFi(Context context) {
        ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();

        boolean isConnected = networkInfo != null
                ? networkInfo.isConnected()
                : false;
        boolean isWiFi = isConnected
                ? networkInfo.getType() == ConnectivityManager.TYPE_WIFI
                : false;

        return isWiFi;
    }

    public static PendingIntent createPendingIntent(Context context, String action) {
        Intent intent = new Intent(context, MarketCollectionReceiver.class);
        intent.setAction(action);
        return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    public static long formatDateStringToDateLong(String update) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        long dateLong = Long.MIN_VALUE;
        Date qDate = null;
        try {
            qDate = sdf.parse(update);
        } catch (ParseException e) {
            e.printStackTrace();
            Log.e(LOG_TAG, "parse update string error");
        }

        if (qDate == null)
            return dateLong;
        Calendar cal = Calendar.getInstance();
        cal.setTime(qDate);
        dateLong = cal.get(Calendar.YEAR) * (100 * 100 * 100 * 100L) +
                cal.get(Calendar.MONTH) * (100 * 100 * 100L) +
                cal.get(Calendar.DAY_OF_MONTH) * (100 * 100L) +
                cal.get(Calendar.HOUR_OF_DAY) * 100L +
                cal.get(Calendar.MINUTE) * 1L;
        return dateLong;
    }

    public static long formatDateToDayLong(Calendar date) {
        long dayLong = Constants.DAY_LONG_MIN;
        if (date == null)
            return dayLong;

        dayLong = date.get(Calendar.YEAR) * (100 * 100L) +
                (date.get(Calendar.MONTH) + 1) * 100L +
                date.get(Calendar.DAY_OF_MONTH) * 1L;
        return dayLong;
    }

    public static Calendar formatDayLongToDate(long dayLong) {
        int year = 1900;
        int month = 1;
        int day = 1;
        if (dayLong > Constants.DAY_LONG_MIN) {
            year = (int) (dayLong / (100 * 100L));
            month = (int) ((dayLong - year * 100 * 100L) / 100L);
            day = (int) (dayLong - year * 100 * 100L - month * 100L);
        }
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, day);
        return cal;
    }

    public static String simpleFormatDateValue(long dayValue) {
        int year = 1900;
        int month = 1;
        int day = 1;
        if (dayValue > Constants.DAY_LONG_MIN) {
            year = (int) (dayValue / (100 * 100L));
            month = (int) ((dayValue - year * 100 * 100L) / 100L);
            day = (int) (dayValue - year * 100 * 100L - month * 100L);
        }
        String simple_fmt_date = String.format("%04d/%02d/%02d", year, month, day);
        return simple_fmt_date;
    }

    public static boolean isAtMarketOpenTime() {
        final Calendar sCalendar = Calendar.getInstance();
        int weekDay = sCalendar.get(Calendar.DAY_OF_WEEK);
        if ((weekDay == Calendar.SATURDAY) && (weekDay == Calendar.SUNDAY))
            return false;
        int month = sCalendar.get(Calendar.MONTH);
        int monthDay = sCalendar.get(Calendar.DAY_OF_MONTH);
        if (month == Calendar.JANUARY && monthDay == 1)
            return false;

        if (month == Calendar.OCTOBER && (monthDay >= 1 && monthDay <= 3))
            return false;

        int hour = sCalendar.get(Calendar.HOUR_OF_DAY);
        int min = sCalendar.get(Calendar.MINUTE);
        int time = hour * 100 + min;
        boolean ret = false;
        if ((time >= 915 && hour <= 1145) ||
                (time >= 1245 && hour <= 1515)) {
            ret = true;
        }
        return ret;
    }

    public static String getJSONFromUrl(String url, int timeoutMillis) {

        HttpURLConnection c = null;
        try {
            URL u = new URL(url);
            c = (HttpURLConnection) u.openConnection();
            c.setRequestMethod("GET");
            c.setRequestProperty("Content-length", "0");
            c.setRequestProperty("Accept", "application/json");
            c.setUseCaches(false);
            c.setAllowUserInteraction(false);
            c.setConnectTimeout(timeoutMillis);
            c.setReadTimeout(timeoutMillis);
            c.connect();
            if (HttpURLConnection.HTTP_OK == c.getResponseCode()) {
                BufferedReader br = new BufferedReader(new InputStreamReader(c.getInputStream()));
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = br.readLine()) != null) {
                    sb.append(line + "\n");
                }
                br.close();
                return sb.toString();
            }

        } catch (MalformedURLException ex) {
            Logger.getLogger("getJSONFromUrl").log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger("getJSONFromUrl").log(Level.SEVERE, null, ex);
        } finally {
            if (c != null) {
                try {
                    c.disconnect();
                } catch (Exception ex) {
                    Logger.getLogger("getJSONFromUrl").log(Level.SEVERE, null, ex);
                }
            }
        }
        return null;
    }

}